#include "CRL_ContextFactory.h"

#include "OpenGL/COGL_ContextFactory.h"
#include "DirectX9/CDX9_ContextFactory.h"
#include "Directx10/CDX10_ContextFactory.h"
#include "Directx11/CDX11_ContextFactory.h"

CB_SUBNAMESPACE_START(RenderLib)

CContextFactory* CContextFactory::s_pInstance = NULL;

// -----------------------------------------------------------------------------------------------------------------

void CContextFactory::Release()					
{ 
    if (IsValid()) 
        delete s_pInstance; 
}

// -----------------------------------------------------------------------------------------------------------------

CContextFactory& CContextFactory::GetInstance()	
{ 
    Debug::Assert(IsValid(), "GetInstance() called on uninitialized singleton.");
    return *s_pInstance; 
}

// -----------------------------------------------------------------------------------------------------------------

bool CContextFactory::IsValid()
{
    return s_pInstance != NULL;
}

// -------------------------------------------------------------------------------

CContextFactory& CContextFactory::CreateInstance(IPlatformHandle& _rHandle)
{
	Release();
    
    switch (_rHandle.GetRenderType())
	{
#ifdef COMPILE_OPENGL
    case RenderType::OpenGL:
        {
            COpenGLHandle& rOGLHandle = static_cast<COpenGLHandle&>(_rHandle);
            s_pInstance = new OpenGL::CContextFactory(rOGLHandle);
            rOGLHandle.m_pContext = static_cast<OpenGL::CContextFactory*>(s_pInstance)->GetSystemContext();
        }
        break;
#endif
        
#ifdef COMPILE_DX9
    case RenderType::DirectX9:
        {
            CDirectXHandle<RenderType::DirectX9>& rDXHandle = static_cast<CDirectXHandle<RenderType::DirectX9>&>(_rHandle);
            s_pInstance = new DX9::CContextFactory(rDXHandle);
            rDXHandle.m_pDevice = static_cast<DX9::CContextFactory*>(s_pInstance)->GetDevice();
        }
        break;
#endif
        
#ifdef COMPILE_DX10
    case RenderType::DirectX10:
        {
            CDirectXHandle<RenderType::DirectX10>& rDXHandle = static_cast<CDirectXHandle<RenderType::DirectX10>&>(_rHandle);
            s_pInstance = new DX10::CContextFactory(rDXHandle);
            rDXHandle.m_pDevice = static_cast<DX10::CContextFactory*>(s_pInstance)->GetDevice();
        }
        break;
#endif
        
#ifdef COMPILE_DX11
    case RenderType::DirectX11:
        {
            CDirectXHandle<RenderType::DirectX11>& rDXHandle = static_cast<CDirectXHandle<RenderType::DirectX11>&>(_rHandle);
            s_pInstance = new DX11::CContextFactory(rDXHandle);
            rDXHandle.m_pDevice = static_cast<DX11::CContextFactory*>(s_pInstance)->GetDevice();
        }
        break;
#endif
        
    default:
        Debug::Error("CContextFactory::CreateInstance could not create a context factory.\n"
                 	 "Unkown RenderType or COMPILE_<render> macro not set");    
        s_pInstance = NULL;
        break;
	}
    
    return *s_pInstance;
}

CB_SUBNAMESPACE_END